home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / GRAPHICS.SWG / 0021_ModeX Code.pas < prev    next >
Pascal/Delphi Source File  |  1993-08-27  |  5KB  |  179 lines

  1. {
  2. MARK DIXON
  3.  
  4. Um, have a look at this, and see what you can come up with. It's some code I
  5. wrote a while back to use mode-x and do double buffering (or page-flipping).
  6. }
  7.  
  8. Program Test_ModeX;
  9.  
  10. Uses
  11.   crt;
  12.  
  13.  
  14. { This program will put the VGA card into a MODEX mode (still only 320x200)
  15.   and demonstrate double buffering (page flipping)
  16.  
  17.   This program was written by Mark Dixon, and has been donated to the
  18.   Public Domain with the exception that if you make use of these routines,
  19.   the author of these routines would appreciate his name mentioned somewhere
  20.   in the documentation.
  21.  
  22.   Use these routines at your own risk! Because they use the VGA's registers,
  23.   cards that are not 100% register compatible may not function correctly, and
  24.   may even be damaged. The author will bear no responsability for any actions
  25.   occuring as a direct (or even indirect) result of the use of this program.
  26.  
  27.   Any donations (eg Money, Postcards, death threats.. ) can be sent to  :
  28.  
  29.   Mark Dixon
  30.   12 Finchley St
  31.   Lynwood,
  32.   Western Australia
  33.   6147
  34.  
  35.   If you have Netmail access, then I can also be contacted on 3:690/660.14
  36.  
  37.   }
  38.  
  39. Const
  40.   Page : Byte = 0;
  41.  
  42. Var
  43.   I, J : Word;
  44.  
  45.  
  46. Procedure InitModeX;
  47. { Sets up video mode to Mode X (320x200x256 with NO CHAIN4) making available
  48.   4 pages of 4x16k bitmaps }
  49. Begin
  50.   asm
  51.     mov    ax, 0013h    { Use bios to enter standard Mode 13h }
  52.     int    10h
  53.     mov    dx, 03c4h    { Set up DX to one of the VGA registers }
  54.     mov    al, 04h      { Register = Sequencer : Memory Modes }
  55.     out    dx, al
  56.     inc    dx           { Now get the status of the register }
  57.     in     al, dx       { from the next port }
  58.     and    al, 0c7h     { AND it with 11000111b ie, bits 3,4,5 wiped }
  59.     or     al, 04h      { Turn on bit 2 (00000100b) }
  60.     out    dx, al       { and send it out to the register }
  61.     mov    dx, 03c4h    { Again, get ready to activate a register }
  62.     mov    al, 02h      { Register = Map Mask }
  63.     out    dx, al
  64.     inc    dx
  65.     mov    al, 0fh      { Send 00001111b to Map Mask register }
  66.     out    dx, al       { Setting all planes active }
  67.     mov    ax, 0a000h   { VGA memory segment is 0a000h }
  68.     mov    es, ax       { load it into ES }
  69.     sub    di, di       { clear DI }
  70.     mov    ax, di       { clear AX }
  71.     mov    cx, 8000h    { set entire 64k memory area (all 4 pages) }
  72.     repnz  stosw        { to colour BLACK (ie, Clear screens) }
  73.     mov    dx, 03d4h    { User another VGA register }
  74.     mov    al, 14h      { Register = Underline Location }
  75.     out    dx, al
  76.     inc    dx           { Read status of register }
  77.     in     al, dx       { into AL }
  78.     and    al, 0bFh     { AND AL with 10111111b }
  79.     out    dx, al       { and send it to the register }
  80.                         { to deactivate Double Word mode addressing }
  81.     dec    dx           { Okay, this time we want another register,}
  82.     mov    al, 17h      { Register = CRTC : Mode Control }
  83.     out    dx, al
  84.     inc    dx
  85.     in     al, dx       { Get status of this register }
  86.     or     al, 40h      { and Turn the 6th bit ON }
  87.     out    dx, al       { to turn WORD mode off }
  88.                         { And thats all there is too it!}
  89.   End;
  90. End;
  91.  
  92.  
  93. Procedure Flip;
  94. { This routine will flip to the next page, and change the value in
  95.   PAGE such that we will allways be drawing to the invisible page. }
  96. Var
  97.   OfsAdr : Word;
  98. Begin
  99.   OfsAdr := Page * 16000;
  100.   asm
  101.     mov    dx, 03D4h
  102.     mov    al, 0Dh      { Set the Start address LOW register }
  103.     out    dx, al
  104.     inc    dx
  105.  
  106.     mov    ax, OfsAdr
  107.     out    dx, al       { by sending low byte of offset address }
  108.     dec    dx
  109.     mov    al, 0Ch      { now set the Start Address HIGH register }
  110.     out    dx, al
  111.     inc    dx
  112.     mov    al, ah
  113.     out    dx, al       { by sending high byte of offset address }
  114.   End;
  115.  
  116.   Page := 1 - Page;     { Flip the page value.
  117.                           Effectively does a :
  118.                           If Page = 0 then Page = 1 else
  119.                           If Page = 1 then Page = 0.       }
  120. End;
  121.  
  122.  
  123.  
  124. Procedure PutPixel (X, Y : Integer; Colour : Byte );
  125. { Puts a pixel on the screen at the current page. }
  126. Var
  127.   OfsAdr : Word;
  128. BEGIN
  129.   OfsAdr := Page * 16000;
  130.   ASM
  131.     mov    bx, x
  132.     mov    ax, Y
  133.     mov    cx, 80     { Since there are now 4 pixels per byte, we
  134.                         only multiply by 80 (320/4) }
  135.     mul    cx
  136.     mov    di, ax
  137.     mov    ax, bx
  138.     shr    ax, 1
  139.     shr    ax, 1
  140.     add    di, ax
  141.     and    bx, 3
  142.     mov    ah, 1
  143.     mov    cl, bl
  144.     shl    ah, cl
  145.  
  146.     mov    al, 2
  147.     mov    dx, 03C4h
  148.  
  149.     mov    bx, $A000
  150.     mov    es, bx
  151.     add    di, OfsAdr
  152.  
  153.     out    dx, ax        { Set plane to address (where AH=Plane) }
  154.     mov    al, Colour
  155.     mov    es:[di], al
  156.   end;
  157. end;
  158.  
  159. Begin
  160.   Randomize;
  161.   InitModeX;
  162.   Flip;
  163.  
  164.   For I := 0 to 319 do
  165.     For J := 0 to 199 do
  166.       PutPixel(I, J, Random(32) );
  167.   Flip;
  168.  
  169.   For I := 0 to 319 do
  170.     For J := 0 to 199 do
  171.       PutPixel(I, J, Random(32) + 32);
  172.  
  173.   Repeat
  174.     Flip;
  175.     Delay(200);
  176.   Until Keypressed;
  177.  
  178. End.
  179.